package com.example.demospringretry.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class TestService {

    /**
     * maxAttempts 最大尝试次数
     *
     * @Backoff(2000) 每次尝试的时间间隔，单位毫秒
     * listeners  配置监听器，执行顺序按照数组顺序执行
     * stateful = true，会导致retry抛出异常，终止重试。stateful = true要求方法必须有参数
     */
    @Retryable(value = RemoteAccessException.class,
            recover = "recover",
            label = "",
            maxAttempts = 3,
            backoff = @Backoff(value = 2000, multiplier = 2))
    public void service(String param, String param1) {
        log.info("do service, p1: {}, p2: {}", param, param1);
        RemoteAccessException e = new RemoteAccessException("测试抛出异常");
        log.error("service 抛出异常");
        throw e;
        // do something...
    }

    @Recover
    public void recover(RemoteAccessException e) {
//        log.error("recover 恢复, {}", arguments);
        log.error("recover 恢复");
        // panic
    }

    @Recover
    public void recover(RemoteAccessException ex, String param, String param1) {
//        log.error("recover 恢复, {}", arguments);

        StackTraceElement stackTraceElement = ex.getStackTrace()[0];
        String className = stackTraceElement.getClassName();
        String methodName = stackTraceElement.getMethodName();
        String s = className + "#" + methodName;

        log.error("recover1 恢复, {}, {}, {}", s, param, param1);
        // panic
    }
}
